package com.hz.score.msg;

import com.hz.score.common.dto.PageDto;
import com.hz.score.common.util.ConvertUtil;
import com.hz.score.cus.dto.CusCommLinkDto;
import com.hz.score.cus.dto.CusIndLinkDto;
import com.hz.score.cus.dto.CusInfoDto;
import com.hz.score.cus.service.CusService;
import com.hz.score.ent.dto.EntBaseInfoDto;
import com.hz.score.ent.dto.EntCommInfoDto;
import com.hz.score.ent.service.EntService;
import com.hz.score.ind.dto.IndInfoDto;
import com.hz.score.ind.service.IndService;
import com.hz.score.msg.event.*;
import com.hz.score.search.document.CommData;
import com.hz.score.search.document.EntScore;
import com.hz.score.search.document.IndData;
import com.hz.score.search.service.SearchService;
import org.springframework.beans.BeanUtils;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class ChangeEventListener {

    @Resource
    SearchService searchService;

    @Resource
    CusService cusService;

    @Resource
    EntService entService;

    @Resource
    IndService indService;

    //TODO，后续可配置
    String year = "2023";
    int pageSize = 100;

    /**
     * 接收企业基础数据变化消息，同步新增或变更Search模块中指定年份数据（默认当年）
     * @param entBaseInfoEvent
     */
    @Async
    @EventListener(EntBaseInfoEvent.class)
    public void handleEntBaseInfo(EntBaseInfoEvent entBaseInfoEvent) {
        EntScore entScore = ConvertUtil.convert(entBaseInfoEvent, EntScore.class);
        entScore.setDataYear(year);
        boolean isNew = searchService.newEntScoreByYear(entScore);
        List<CusInfoDto> cusInfoDtoList = cusService.getAllParentByBizTyp(entBaseInfoEvent.getBizTyp());
        List<String> bizTyps = cusInfoDtoList.stream().map(cusInfoDto -> cusInfoDto.getBizTyp()).collect(Collectors.toList());
        //如果是新增企业
        if (isNew) {
            //添加系统用户已关联的经营信息数据
            List<CusCommLinkDto> cusCommLinkDtoList = cusService.listLinkCommByBizTyes(bizTyps);
            if (!CollectionUtils.isEmpty(cusCommLinkDtoList)) {
                List<Long> ids = cusCommLinkDtoList.stream().map(CusCommLinkDto::getCommId).collect(Collectors.toList());
                List<EntCommInfoDto> entCommInfoDtoList = entService.getCommEnts(ids);
                if (!CollectionUtils.isEmpty(entCommInfoDtoList)) {
                    entCommInfoDtoList.forEach(entCommInfoDto -> {
                        CommData commData = new CommData();
                        BeanUtils.copyProperties(entCommInfoDto, commData);
                        searchService.newCommData(entBaseInfoEvent.getCreCod(), year, commData);
                    });
                }
            }
            //添加系统用户已关联的企业指标数据
            List<CusIndLinkDto> cusIndLinkDtoList = cusService.listLinkIndByBizTyes(bizTyps);
            if (!CollectionUtils.isEmpty(cusIndLinkDtoList)) {
                List<Long> ids = cusIndLinkDtoList.stream().map(CusIndLinkDto::getIndId).collect(Collectors.toList());
                List<IndInfoDto> indInfoDtoList = indService.getIndEnts(ids);
                if (!CollectionUtils.isEmpty(indInfoDtoList)) {
                    indInfoDtoList.forEach(entIntInfoDto -> {
                        IndData indData = new IndData();
                        BeanUtils.copyProperties(entIntInfoDto, indData);
                        searchService.newIndData(entBaseInfoEvent.getCreCod(), year, indData);
                    });
                }
            }
        }
    }

    /**
     * 接收企业新增关联经营数据消息，同步更新关联信息到Search模块中指定年份数据（默认当年）
     * @param cusCommLinkEvent
     */
    @Async
    @EventListener(CusCommLinkEvent.class)
    public void handleCusCommLink(CusCommLinkEvent cusCommLinkEvent) {
        EntCommInfoDto entCommInfoDto = entService.getCommEnt(cusCommLinkEvent.getCommId());
        List<CusInfoDto> cusInfoDtoList =  cusService.getAllChild(cusCommLinkEvent.getBizTyp());
        for (CusInfoDto cusInfoDto : cusInfoDtoList) {
            EntBaseInfoDto entBaseInfoDto = new EntBaseInfoDto();
            entBaseInfoDto.setBizTyp(cusInfoDto.getBizTyp());
            CommData commData = new CommData();
            BeanUtils.copyProperties(entCommInfoDto, commData);
            PageDto<EntBaseInfoDto> pageDto;
            int pageNum = 1;
            do { //查询客户下所有关联企业，并添加新增经营数据信息
                pageDto = entService.pageBaseEnt(entBaseInfoDto, pageSize, pageNum++);
                if (pageDto.getRecords().size() > 0) {
                    List<EntBaseInfoDto> entBaseInfoDtoList = pageDto.getRecords();
                    entBaseInfoDtoList.forEach(entBaseInfoDtoIt -> {
                        searchService.newCommData(entBaseInfoDtoIt.getCreCod(), year, commData);
                    });
                }
            } while (pageDto.getRecords().size() == pageSize);
        }
    }

    /**
     * 接收企业取消关联经营数据消息，同步删除关联信息到Search模块中指定年份数据（默认当年）
     * @param cusCommUnlinkEvent
     */
    @Async
    @EventListener(CusCommUnlinkEvent.class)
    public void handleCusCommUnlink(CusCommUnlinkEvent cusCommUnlinkEvent) {
        EntCommInfoDto entCommInfoDto = entService.getCommEnt(cusCommUnlinkEvent.getCommId());
        List<CusInfoDto> cusInfoDtoList =  cusService.getAllChild(cusCommUnlinkEvent.getBizTyp());
        for (CusInfoDto cusInfoDto : cusInfoDtoList) {
            EntBaseInfoDto entBaseInfoDto = new EntBaseInfoDto();
            entBaseInfoDto.setBizTyp(cusInfoDto.getBizTyp());
            PageDto<EntBaseInfoDto> pageDto;
            int pageNum = 1;
            do { //查询客户下所有关联企业，并删除指标信息
                pageDto = entService.pageBaseEnt(entBaseInfoDto, pageSize, pageNum++);
                if (pageDto.getRecords().size() > 0) {
                    List<EntBaseInfoDto> entBaseInfoDtoList = pageDto.getRecords();
                    entBaseInfoDtoList.forEach(entBaseInfoDtoIt -> {
                        searchService.delCommData(entBaseInfoDtoIt.getCreCod(), year, entCommInfoDto.getCode());
                    });
                }
            } while (pageDto.getRecords().size() == pageSize);
        }
    }

    /**
     * 接收企业新增关联指标消息，同步更新关联信息到Search模块中指定年份数据（默认当年）
     * @param cusIndLinkEvent
     */
    @Async
    @EventListener(CusIndLinkEvent.class)
    public void handleCusCommLink(CusIndLinkEvent cusIndLinkEvent) {
        IndInfoDto indInfoDto = indService.getIndEnt(cusIndLinkEvent.getIndId());
        List<CusInfoDto> cusInfoDtoList =  cusService.getAllChild(cusIndLinkEvent.getBizTyp());
        for (CusInfoDto cusInfoDto : cusInfoDtoList) {
            IndData indData = new IndData();
            BeanUtils.copyProperties(indInfoDto, indData);
            EntBaseInfoDto entBaseInfoDto = new EntBaseInfoDto();
            entBaseInfoDto.setBizTyp(cusInfoDto.getBizTyp());
            PageDto<EntBaseInfoDto> pageDto;
            int pageNum = 1;
            do { //查询客户下所有关联企业，并添加新增指标信息
                pageDto = entService.pageBaseEnt(entBaseInfoDto, pageSize, pageNum++);
                if (pageDto.getRecords().size() > 0) {
                    List<EntBaseInfoDto> entBaseInfoDtoList = pageDto.getRecords();
                    entBaseInfoDtoList.forEach(entBaseInfoDtoIt -> {
                        searchService.newIndData(entBaseInfoDtoIt.getCreCod(), year, indData);
                    });
                }
            } while (pageDto.getRecords().size() == pageSize);
        }
    }

    /**
     * 接收企业取消关联指标消息，同步更新关联信息到Search模块中指定年份数据（默认当年）
     * @param cusIndUnlinkEvent
     */
    @Async
    @EventListener(CusIndUnlinkEvent.class)
    public void handleCusCommLink(CusIndUnlinkEvent cusIndUnlinkEvent) {
        IndInfoDto indInfoDto = indService.getIndEnt(cusIndUnlinkEvent.getIndId());
        List<CusInfoDto> cusInfoDtoList =  cusService.getAllChild(cusIndUnlinkEvent.getBizTyp());
        for (CusInfoDto cusInfoDto : cusInfoDtoList) {
            EntBaseInfoDto entBaseInfoDto = new EntBaseInfoDto();
            entBaseInfoDto.setBizTyp(cusInfoDto.getBizTyp());
            PageDto<EntBaseInfoDto> pageDto;
            int pageNum = 1;
            do { //查询客户下所有关联企业，并删除指标信息
                pageDto = entService.pageBaseEnt(entBaseInfoDto, pageSize, pageNum++);
                if (pageDto.getRecords().size() > 0) {
                    List<EntBaseInfoDto> entBaseInfoDtoList = pageDto.getRecords();
                    entBaseInfoDtoList.forEach(entBaseInfoDtoIt -> {
                        searchService.delIndData(entBaseInfoDtoIt.getCreCod(), year, indInfoDto.getCode());
                    });
                }
            } while (pageDto.getRecords().size() == pageSize);
        }
    }
}
